﻿using System;
using System.Configuration;
using System.Web;
using System.Web.Hosting;
using AutoProbe.ProbeWebService;
using Medianamik.Core.Action;
using Medianamik.Core.Configuration;
using Medianamik.Core.Security;

namespace Medianamik.Core.Bootstrapping
{
    public abstract class Bootstrapper
    {
        private static readonly MedianamikConfigSection Config =
            (MedianamikConfigSection)ConfigurationManager.GetSection(ConfigurationSectionName.MEDIANAMIK);

        private static readonly Object ThisLock = new Object();

        public abstract void Configure(HttpApplication pApplication);
        public abstract void Cleanup(HttpApplication pApplication);

        protected virtual void RegisterVirtualPathProvider(VirtualPathProvider pProvider)
        {
            HostingEnvironment.RegisterVirtualPathProvider(pProvider);
        }

        protected virtual void ProbeAutoDocService(HttpApplication pApplication)
        {
            var probe = new Probing();
            probe.ProbeAsync(new AutoProbe.ProbeInfos().GetHostingInfos());
        }

        public virtual void RegisterActionHandlers()
        {
            ActionManager.RegisterActionHandler<IndexActionHandler>();
            ActionManager.RegisterActionHandler<NodeTypeGenTableActionHandler>();
            ActionManager.RegisterActionHandler<Urls.UrlChangedActionHandler>();
            ActionManager.RegisterActionHandler<UserProfileActionHandler>();
            ActionManager.RegisterActionHandler<UpdateGenTableActionHandler>();
            ActionManager.RegisterActionHandler<UserHandler>();
            ActionManager.RegisterActionHandler<Redirect.RedirectUrlChangedActionHandler>();
            ActionManager.RegisterActionHandler<Logging.LoggingActionHandler>();
            ActionManager.RegisterActionHandler(String.IsNullOrEmpty(Config.UrlActionHandler) ?
                "Medianamik.UI.Controls.UrlActionHandler, Medianamik.UI" :
                Config.UrlActionHandler);
            ActionManager.RegisterActionHandler("Medianamik.UI.Lock.ReleaseLockAction, Medianamik.UI");
            ActionManager.RegisterActionHandler("Medianamik.Client.SqlCacheDependencyActionHandler, Medianamik.Client");
        }

        public void SafeConfigure(HttpApplication pApplication)
        {
            if (pApplication.Application["BOOTSTRAPPER"] == null)
                lock (ThisLock)
                    if (pApplication.Application["BOOTSTRAPPER"] == null)
                    {
                        Configure(pApplication);
                        pApplication.Application["BOOTSTRAPPER"] = DateTime.Now;
                    }
        }

        public static Bootstrapper GetBootstrapper(ApplicationEnvironment pType)
        {
            switch (pType)
            {
                case ApplicationEnvironment.Production:
                    return new ProductionBootstrapper();
                case ApplicationEnvironment.ClientDevelopment:
                    return new ClientDevelopmentBootstrapper();
                case ApplicationEnvironment.MedianamikDevelopment:
                    return new MedianamikDevelopmentBootstrapper();
                case ApplicationEnvironment.Auto:
                    return new AutoBootstrapper();
                default:
                    throw new ArgumentException("pType");
            }
        }
        public static Bootstrapper GetBootstrapper()
        {
            return GetBootstrapper(ApplicationEnvironment.Auto);
        }

        public void AuthenticateRequestNeeded()
        {
            ActionManager.Instance.OnAuthenticationRequested(new ActionEventArgs<object>(null));
        }
    }

    public enum ApplicationEnvironment
    {
        MedianamikDevelopment,
        ClientDevelopment,
        Production,
        Auto
    }
}